home *** CD-ROM | disk | FTP | other *** search
- /*
- * $VER:SnapGfx.c - (11.09.95) 17:39:11 Copyright © 1995 by Mikael Karlsson & Sylvain ROUGIER
- *
- * Created: 1988
- * Modified: 11 Sep 1995 17:39:11
- *
- * Make>> smake
- *
- * 09/09/95:
- * fix, to save 8bit per gun palette under V39+
- *
- * 10/09/95:
- * Now Alloc dynamaicaly BitMap struct. (future usage of AllocBitMap())
- */
-
- #include "Snap.h"
-
- #include "proto/Misc.h"
- #include "proto/GfxSnap.h"
-
- IMPORT BOOL Kick36;
-
- IMPORT struct GfxBase *GfxBase;
-
- IMPORT struct SnapRsrc *SnapRsrc;
- IMPORT struct Image DiskImage;
- IMPORT struct Image ClipImage;
- IMPORT struct Gadget DiskGad;
- IMPORT struct Gadget ClipGad;
- IMPORT struct Gadget VProp, HProp;
- IMPORT struct PropInfo VInfo, HInfo;
- IMPORT struct Image VImage, HImage;
- IMPORT struct NewWindow Nw;
- IMPORT UBYTE *WindowTitle;
-
- IMPORT LONG xl; /* leftmost x position */
- IMPORT LONG xr; /* rightmost x position */
- IMPORT LONG yt; /* topmost y position */
- IMPORT LONG yb; /* bottommost y position */
- IMPORT LONG mx, my; /* Mouse position in pixels */
-
- #define GfxFrame 4L
- IMPORT Point OldFrame[ ];
- IMPORT Point NewFrame[ ];
- IMPORT LONG OFType; /* Old frame type: ShortFrame/LongFrame */
- IMPORT UWORD Ptrn;
- IMPORT WORD Pattern[ ];
-
- IMPORT struct RastPort MyRP;
- IMPORT struct BitMap MyBM;
- IMPORT struct Screen *theScreen;
- IMPORT struct RastPort rp;
-
- IMPORT struct timerequest MyTR;
-
- IMPORT LONGBITS cancelsignal, donesignal, movesignal;
- IMPORT LONGBITS clicksignal, ticksignal, timersignal;
- IMPORT WORD action;
-
- LONG TopBar;
- LONG LeftBar;
- LONG RightBar;
- LONG BottomBar;
- LONG ScreenFontHeight;
- struct TextFont *ScreenFont;
-
- VOID FixHeights( )
- {
- struct Screen WBScreen;
-
- OpenWorkBench( );
- if ( GetScreenData( ( char *)&WBScreen, ( LONG) sizeof ( struct Screen), WBENCHSCREEN, NULL))
- {
- /* Now this is a good practice */
- TopBar = WBScreen.WBorTop + WBScreen.RastPort.TxHeight + 1;
- LeftBar = WBScreen.WBorLeft;
- RightBar = WBScreen.WBorRight;
- BottomBar = WBScreen.WBorBottom;
- ScreenFont = WBScreen.RastPort.Font;
- if ( !ScreenFont)
- {
- Forbid( );
- ScreenFont = GfxBase->DefaultFont;
- Permit( );
- }
- ScreenFontHeight = ScreenFont->tf_YSize;
- }
- else
- {
- /* Sorry, but I don't realise how this could fail.
- Well, if we're snapping on another screen and
- WB is closed and it can't be opened by GetScreenData( )...
- Anyway, IF this should happen -- Use Topaz 8 */
- TopBar = 10;
- LeftBar = 2;
- RightBar = 2;
- BottomBar = 1;
- ScreenFontHeight = 8;
- Forbid( );
- ScreenFont = GfxBase->DefaultFont;
- Permit( );
- }
- }
-
-
- struct GfxSnap *CreateGfxSnap( void)
- {
- struct GfxSnap *GfxSnap;
-
- if ( GfxSnap = AllocVec( sizeof( struct GfxSnap), MEMF_ANY|MEMF_CLEAR))
- {
- return GfxSnap;
- }
-
- return NULL;
- }
-
- void DeleteGfxSnap( struct GfxSnap *GfxSnap)
- {
- if ( GfxSnap)
- {
- if ( GfxSnap->BitMap)
- {
- Snp_FreeBitMap( GfxSnap->BitMap, GfxSnap->width, GfxSnap->height);
- }
- FreeVec( GfxSnap);
- }
-
- return;
- }
-
- static void CopyColorDefs( ULONG Depth, struct ColorMap *ColorMap, UBYTE RGB8[][3])
- {
- ULONG i = Depth;
-
- if ( SysBase->LibNode.lib_Version < 39)
- {
- ULONG col;
-
- while ( i-- && ( col = GetRGB4( ColorMap, i)) != -1L)
- {
- RGB8[ i][ 0] = RGB4ToRR( col);
- RGB8[ i][ 1] = RGB4ToGG( col);
- RGB8[ i][ 2] = RGB4ToBB( col);
- }
- }
- else
- {
- while ( i--)
- {
- ULONG RGB[ 3];
-
- GetRGB32( ColorMap, i, 1, RGB);
- RGB8[ i][ 0] = RGB32ToRGB8( RGB[ 0]);
- RGB8[ i][ 1] = RGB32ToRGB8( RGB[ 1]);
- RGB8[ i][ 2] = RGB32ToRGB8( RGB[ 2]);
- }
- }
- }
-
- /* SnapGfx is the actual graphics snapper.
- ** It steals the bitmap data from the given rastport
- ** and puts it in a separate bitmap.
- ** It also prepares the NewWindow structure according
- ** to the snapped bitmap.
- ** The coordinates are assumed to be valid.
- */
- struct GfxSnap * SnapGfx( struct RastPort *rp)
- {
- struct GfxSnap *GS;
- LONG i;
-
- GS = CreateGfxSnap();
- if ( !GS)
- {
- return NULL;
- }
-
- GS->x = xl;
- GS->y = yt;
- GS->width = xr - xl + 1;
- GS->height = yb - yt + 1;
- if ( xr < xl + MINWIDTH)
- { /* Can't have too small windows */
- xr = xl + MINWIDTH;
- }
- if ( yb < yt + MINHEIGHT)
- {
- yb = yt + MINHEIGHT;
- }
- GS->depth = rp->BitMap->Depth;
- GS->viewmode = theScreen->ViewPort.Modes;
- GS->pagew = theScreen->Width;
- GS->pageh = theScreen->Height;
- i = ( GS->viewmode & HAM ? 16 : 1L << GS->depth);
- /* Copy the color map in case we should need it later */
- CopyColorDefs(
- GS->viewmode & HAM ?
- 16 :
- 1L << GS->depth,
- theScreen->ViewPort.ColorMap,
- GS->rgb);
-
- /* Set up a nice bitmap */
- InitRastPort( &MyRP);
- MyRP.BitMap = GS->BitMap = AllocBitMap( GS->width, GS->height, GS->depth, BMF_DISPLAYABLE, rp->BitMap);
- if ( !GS->BitMap)
- {
- DeleteGfxSnap( GS);
- return NULL;
- }
-
- /* Copy the selected part of the screen */
- ClipBlit( rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
- if ( !Kick36)
- {
- VInfo.Flags |= PROPBORDERLESS;
- HInfo.Flags |= PROPBORDERLESS;
- }
- CopyMem( ( char *)&DiskGad, ( char *)&GS->DiskGad, ( LONG) sizeof ( DiskGad) + sizeof ( ClipGad) + sizeof ( VProp) + sizeof ( HProp) + sizeof ( VInfo) + sizeof ( HInfo) + sizeof ( VImage) + sizeof ( HImage));
- GS->topbar = TopBar;
- GS->leftbar = LeftBar;
- GS->rightbar = 18; /* ( Kick36 ? RightBar : 18); */
- GS->bottombar = 10;
-
- Nw.LeftEdge = xl;
- Nw.TopEdge = yt;
- Nw.Width = xr - xl + 1 + GS->leftbar + GS->rightbar;
- Nw.Height = yb - yt + 1 + GS->topbar + GS->bottombar;
- Nw.Flags &= ~( SIMPLE_REFRESH | SMART_REFRESH | NOCAREREFRESH);
- Nw.Flags |= ( SnapRsrc->flags & SIMPLEREFRESH ?
- SIMPLE_REFRESH :
- SMART_REFRESH | NOCAREREFRESH);
-
- Nw.Title = WindowTitle;
- Nw.MinWidth = MINWIDTH + 1 + GS->leftbar + GS->rightbar;
- Nw.MinHeight = MINHEIGHT + 1 + GS->topbar + GS->bottombar;
- Nw.MaxWidth = Nw.Width;
- Nw.MaxHeight = Nw.Height;
-
- if ( Kick36)
- Nw.Flags |= SIZEBBOTTOM | SIZEBRIGHT;
-
- return GS;
- }
-
- VOID ExtendGfx( )
- {
- /* Fix which row we're talking about */
- if ( my - yt < yb - my)
- { /* Find closest row */
- yt = my; /* change top row */
- }
- else
- {
- yb = my; /* change bottom row */
- }
- if ( mx - xl < xr - mx)
- {
- xl = mx;
- }
- else
- {
- xr = mx;
- }
- }
-
- VOID gfx_frame( )
- {
- NewFrame[ 0].x = xl;
- NewFrame[ 0].y = yt;
- NewFrame[ 1].x = xr;
- NewFrame[ 1].y = yt;
- NewFrame[ 2].x = xr;
- NewFrame[ 2].y = yb;
- NewFrame[ 3].x = xl;
- NewFrame[ 3].y = yb;
- NewFrame[ 4].x = xl;
- NewFrame[ 4].y = yt;
- draw_frame( GfxFrame);
- }
-
- WORD HandleGfx( void)
- {
- struct Layer_Info *LockedLayerInfo;
-
- theScreen = WhichScreen( ); /* Find out where we are */
- if ( !theScreen)
- { /* Don't know? Forget it. */
- action = noaction;
- return 0;
- }
- /* Lock everything - find out what happens */
- LockedLayerInfo = &theScreen->LayerInfo;
- // LockLayers( LockedLayerInfo);
-
- /* Get a copy. Don't mess with somebody else's RP. */
- CopyMem( ( char *)&theScreen->RastPort, ( char *)&rp, ( long)sizeof ( struct RastPort));
-
- SetDrMd( &rp, COMPLEMENT);
-
- xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
- if ( xl < 0)
- {
- xl = 0;
- }
- if ( xl >= theScreen->Width)
- { /* Check those corners. Check those corners. */
- xl = theScreen->Width - 1;
- }
- yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
- if ( yt < 0)
- {
- yt = 0;
- }
- if ( yt >= theScreen->Height)
- {
- yt = theScreen->Height - 1;
- }
- xr = xl;
- yb = yt;
- Ptrn = ( SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[ UNIT_FRAME]);
- OFType = 0L;
- gfx_frame( );
-
- FOREVER
- {
- REGISTER LONGBITS sig;
-
- MyTR.tr_time.tv_secs = 0;
- MyTR.tr_time.tv_micro = 500000;
- MyTR.tr_node.io_Command = TR_ADDREQUEST;
- SendIO( ( struct IORequest *)&MyTR);
-
- sig = Wait( movesignal | clicksignal | cancelsignal | donesignal | ticksignal | timersignal);
-
- if ( CheckIO( ( struct IORequest *)&MyTR))
- {
- WaitIO( ( struct IORequest *)&MyTR);
- erase_frame( );
- // UnlockLayers( LockedLayerInfo); /* Unlock things */
- sig = Wait( ticksignal); /* Wait for input handler to become avtive */
- // LockLayers( LockedLayerInfo); /* Re-lock */
- /* I guess I should check to see that the window is still
- there. Aw, what the heck. Apologies to anyone who gets
- bitten by this. */
- DisplayBeep( NULL);
- gfx_frame( );
- }
- else
- {
- AbortIO( ( struct IORequest *)&MyTR);
- WaitIO( ( struct IORequest *)&MyTR);
- SetSignal( 0, timersignal);
- }
-
- if ( ( sig & ticksignal) && ( SnapRsrc->CrawlPtrn != 0xffff))
- {
- crawl_frame( 1L);
- }
-
- if ( sig & movesignal || sig & clicksignal)
- {
- mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
- if ( mx < 0)
- {
- mx = 0;
- }
- if ( mx >= theScreen->Width)
- {
- mx = theScreen->Width - 1;
- }
- my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
- if ( my < 0)
- {
- my = 0;
- }
- if ( my >= theScreen->Height)
- {
- my = theScreen->Height - 1;
- }
- ExtendGfx( );
- gfx_frame( );
- }
- if ( sig & cancelsignal)
- { /* Cancelled? */
- erase_frame( );
- // UnlockLayers( LockedLayerInfo);
- return 0;
- }
- if ( sig & donesignal)
- { /* Finished. Copy gfx. */
- struct GfxSnap *GS;
-
- erase_frame( );
- if ( xl == xr || yt == yb)
- {
- action = noaction;
- // UnlockLayers( LockedLayerInfo);
- return 0;
- }
- if ( xr >= theScreen->Width)
- {
- xl -= xr - theScreen->Width - 1;
- xr = theScreen->Width - 1;
- }
- if ( yb >= theScreen->Height)
- {
- yt -= yb - theScreen->Height - 1;
- yb = theScreen->Height - 1;
- }
- FixHeights( );
- GS = SnapGfx( &rp); /* Snap! */
- // UnlockLayers( LockedLayerInfo);
- if ( GS)
- {
- if ( GS->window = opensharedwindow( &Nw))
- {
- if ( SnapRsrc->flags & SIMPLEREFRESH)
- {
- ModifyIDCMP( GS->window,
- GS->window->IDCMPFlags | REFRESHWINDOW);
- }
- if ( Kick36)
- {
- GS->topbar = GS->window->BorderTop;
- GS->leftbar = GS->window->BorderLeft;
- GS->rightbar = GS->window->BorderRight;
- GS->bottombar = 10; /*GS->window->BorderBottom; */
-
- GS->HProp.TopEdge = -7;
- GS->HProp.Height = 6;
- }
-
- GS->DiskGad.TopEdge = GS->topbar;
- GS->DiskGad.LeftEdge = ( Kick36 ? -17 : -14);
- GS->DiskGad.Width = ( Kick36 ? 18 : 14);
- GS->ClipGad.TopEdge = GS->DiskGad.TopEdge + 12;
- GS->ClipGad.LeftEdge = ( Kick36 ? -17 : -14);
- GS->ClipGad.Width = ( Kick36 ? 18 : 14);
- GS->HProp.GadgetRender = ( APTR) & GS->HImage;
- GS->HProp.SpecialInfo = ( APTR) & GS->HInfo;
- GS->VProp.TopEdge =
- GS->ClipGad.TopEdge + ( Kick36 ? 14 : 15);
- GS->VProp.LeftEdge = ( Kick36 ? 5 : 7) - GS->rightbar;
- GS->VProp.Width = GS->rightbar - ( Kick36 ? 8 : 10);
- GS->VProp.Height =
- ( Kick36 ? -28 : -27) - GS->bottombar - GS->topbar;
- GS->VProp.GadgetRender = ( APTR) & GS->VImage;
- GS->VProp.SpecialInfo = ( APTR) & GS->VInfo;
-
- GS->DiskGad.NextGadget = &GS->ClipGad;
- GS->ClipGad.NextGadget = &GS->VProp;
- GS->VProp.NextGadget = &GS->HProp;
- GS->HProp.NextGadget = NULL;
-
- AddGList( GS->window, &GS->DiskGad, -1, -1, NULL);
- GS->window->UserData = ( BYTE *) GS;
- /* Put gfx in our new window */
- AdjustSize( GS);
- }
- else
- {
- DeleteGfxSnap( GS);
- }
- }
- else
- { /* Good question */
- }
- action = noaction;
- return 0;
- }
- }
- }
-